package edu.towson.cosc.cosc455.dspenc5.compiler;

import edu.towson.cosc.cosc455.interfaces.LexicalAnalyzer;


public class MyLexicalAnalyzer implements LexicalAnalyzer {
	/*
	 * 
	 * @see edu.towson.cosc.cosc455.interfaces.LexicalAnalyzer#getNextToken()
	 */

    /** The next character. */
    private String nextCharacter = "";
    
    /** The current position. */
    int currentPosition = 0;
    
    /**
	 * @return the currentPosition
	 */
	public int getCurrentPosition() {
		return currentPosition;
	}

	/**
	 * @return the completeCode
	 */
	public String getCompleteCode() {
		return completeCode;
	}

	/** Stores complete lolcode text in one string*/
    String completeCode = "";
    
    
    //Constructor
    public MyLexicalAnalyzer(String s) {
		completeCode = s;
	}
	
	@Override
	public void getNextToken() {
		MyCompiler.token = "";
		addCharacter();
		while(isSpace(MyCompiler.token)){//eats up extra whitespace
			addCharacter();
		}
		if(isHashtag(MyCompiler.token)){//processes lexical tokens
			processTag();
			if(!lookupToken()){
				System.err.println("Lexical error: " + MyCompiler.token +
						" is not a legal lolcode token.");
				System.exit(0);
			}
		}
		else{//everything not already processed should be text
			processText();
		}
	}

	/**
	 * collects text after a hashtag until a space is reached
	 */
	private void processTag() {
		getCharacter();
		while(!isSpace(nextCharacter) && hasNextChar()){
			MyCompiler.token = MyCompiler.token + nextCharacter;
			getCharacter();
		}
		if(!hasNextChar())
			MyCompiler.token = MyCompiler.token + nextCharacter;
		if(MyCompiler.token.contains("#")){
			if(!lookupToken())//attempt to process two word tags
				processMultiWordTag();
			if(!lookupToken())//attempt to process three word tags
				processMultiWordTag();
		}
	}

	/**
	 * gathers text to be appended to a token after a space
	 */
	private void processMultiWordTag() {
		MyCompiler.token = MyCompiler.token + nextCharacter;
		getCharacter();
		while(!isSpace(nextCharacter) && hasNextChar()){
			MyCompiler.token = MyCompiler.token + nextCharacter;
			getCharacter();
		}
		if(!hasNextChar())
			MyCompiler.token = MyCompiler.token + nextCharacter;
	}
	
	@Override
	public void getCharacter() {
		if(!hasNextChar()){
			//while looking for valid token reached eof
			System.err.println("Lexical error: reached end of file and "
					+ MyCompiler.token + " is not a valid token.");
			System.exit(0);
		}
		char current = completeCode.charAt(currentPosition);//current char equals charAt current position in code
		nextCharacter = current + "";
		currentPosition++;
	}

	@Override
	public void addCharacter() {
		getCharacter();
		MyCompiler.token = MyCompiler.token + nextCharacter;
	}

	@Override
	public boolean isSpace(String c) {
		return (c.equalsIgnoreCase(" ")||c.equalsIgnoreCase("\r")||c.equalsIgnoreCase("\n"));
	}

	@Override
	public boolean lookupToken() {
		return(LexicalTokens.isPossibleToken(MyCompiler.token));
	}
	/**
	 * returns true if current character is equal to a hashtag
	 */
	private boolean isHashtag(String s) {
		return s.equals("#");
	}
	/**
	 * @return true if there is still more code to be processed 
	 */
	public boolean hasNextChar() {
		return (currentPosition < completeCode.length());
	}
	/**
	 * adds characters to token until a hashtag is found
	 */
	public void processText(){
		while(!isHashtag(nextCharacter) && hasNextChar()){
                getCharacter();
                if(!isHashtag(nextCharacter))
                        MyCompiler.token += nextCharacter;
        }
        if(nextCharacter.equals("#")){
                currentPosition--;
        }
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
	}
}
